package com.example.service;

import com.example.model.ChatMessage;
import com.example.repository.ChatMessageRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 聊天服务类
 */
@Slf4j
@Service
public class ChatService {

    @Autowired
    private ChatMessageRepository chatMessageRepository;

    @Autowired
    private WebSocketService webSocketService;

    /**
     * 发送聊天消息
     */
    @Transactional
    public ChatMessage sendMessage(String senderId, String receiverId, String content, 
                                  ChatMessage.MessageType messageType, String extraData) {
        
        // 创建消息对象
        ChatMessage message = new ChatMessage();
        message.setSenderId(senderId);
        message.setReceiverId(receiverId);
        message.setContent(content);
        message.setMessageType(messageType);
        message.setStatus(ChatMessage.MessageStatus.SENT);
        message.setExtraData(extraData);
        message.setCreatedAt(LocalDateTime.now());

        // 保存到数据库
        ChatMessage savedMessage = chatMessageRepository.save(message);
        
        log.info("保存聊天消息: id={}, from={}, to={}, type={}", 
                savedMessage.getId(), senderId, receiverId, messageType);

        // 通过WebSocket发送给接收者
        webSocketService.sendChatMessage(senderId, receiverId, content, messageType.name());

        return savedMessage;
    }

    /**
     * 获取聊天历史记录
     */
    public List<ChatMessage> getChatHistory(String userId1, String userId2) {
        return chatMessageRepository.findChatHistory(userId1, userId2);
    }

    /**
     * 分页获取聊天历史记录
     */
    public Page<ChatMessage> getChatHistory(String userId1, String userId2, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        return chatMessageRepository.findChatHistory(userId1, userId2, pageable);
    }

    /**
     * 获取用户的聊天对话列表
     */
    public List<String> getChatPartners(String userId) {
        return chatMessageRepository.findChatPartners(userId);
    }

    /**
     * 获取用户未读消息数量
     */
    public Long getUnreadMessageCount(String userId) {
        return chatMessageRepository.countUnreadMessages(userId);
    }

    /**
     * 获取两个用户之间的未读消息数量
     */
    public Long getUnreadMessageCountBetween(String senderId, String receiverId) {
        return chatMessageRepository.countUnreadMessagesBetween(senderId, receiverId);
    }

    /**
     * 标记消息为已读
     */
    @Transactional
    public void markMessageAsRead(Long messageId) {
        chatMessageRepository.markAsRead(messageId, LocalDateTime.now());
        log.debug("标记消息为已读: messageId={}", messageId);
    }

    /**
     * 批量标记消息为已读
     */
    @Transactional
    public void markMessagesAsRead(List<Long> messageIds) {
        if (messageIds != null && !messageIds.isEmpty()) {
            chatMessageRepository.markAsReadBatch(messageIds, LocalDateTime.now());
            log.debug("批量标记消息为已读: count={}", messageIds.size());
        }
    }

    /**
     * 标记两个用户之间的所有消息为已读
     */
    @Transactional
    public void markAllMessagesAsReadBetween(String senderId, String receiverId) {
        chatMessageRepository.markAllAsReadBetween(senderId, receiverId, LocalDateTime.now());
        log.info("标记所有消息为已读: from={}, to={}", senderId, receiverId);
    }

    /**
     * 获取用户最新消息
     */
    public Page<ChatMessage> getLatestMessages(String userId, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        return chatMessageRepository.findLatestMessages(userId, pageable);
    }

    /**
     * 根据时间范围获取消息
     */
    public List<ChatMessage> getMessagesBetweenTime(String userId1, String userId2, 
                                                   LocalDateTime startTime, LocalDateTime endTime) {
        return chatMessageRepository.findMessagesBetweenTime(userId1, userId2, startTime, endTime);
    }

    /**
     * 根据消息类型获取消息
     */
    public List<ChatMessage> getMessagesByType(ChatMessage.MessageType messageType) {
        return chatMessageRepository.findByMessageTypeOrderByCreatedAtDesc(messageType);
    }

    /**
     * 获取用户发送的消息
     */
    public List<ChatMessage> getSentMessages(String senderId) {
        return chatMessageRepository.findBySenderIdOrderByCreatedAtDesc(senderId);
    }

    /**
     * 获取用户接收的消息
     */
    public List<ChatMessage> getReceivedMessages(String receiverId) {
        return chatMessageRepository.findByReceiverIdOrderByCreatedAtDesc(receiverId);
    }

    /**
     * 获取消息详情
     */
    public Optional<ChatMessage> getMessageById(Long messageId) {
        return chatMessageRepository.findById(messageId);
    }

    /**
     * 删除消息
     */
    @Transactional
    public void deleteMessage(Long messageId) {
        chatMessageRepository.deleteById(messageId);
        log.info("删除消息: messageId={}", messageId);
    }

    /**
     * 清理过期消息
     */
    @Transactional
    public void cleanupOldMessages(int daysToKeep) {
        LocalDateTime cutoffTime = LocalDateTime.now().minusDays(daysToKeep);
        chatMessageRepository.deleteMessagesBeforeTime(cutoffTime);
        log.info("清理{}天前的消息", daysToKeep);
    }

    /**
     * 发送系统消息
     */
    @Transactional
    public ChatMessage sendSystemMessage(String receiverId, String content) {
        return sendMessage("system", receiverId, content, ChatMessage.MessageType.SYSTEM, null);
    }

    /**
     * 发送订单咨询消息
     */
    @Transactional
    public ChatMessage sendOrderInquiry(String senderId, String receiverId, String content, Long orderId) {
        String extraData = "{\"orderId\":" + orderId + "}";
        return sendMessage(senderId, receiverId, content, ChatMessage.MessageType.ORDER_INQUIRY, extraData);
    }

    /**
     * 发送服务咨询消息
     */
    @Transactional
    public ChatMessage sendServiceInquiry(String senderId, String receiverId, String content, Long serviceId) {
        String extraData = "{\"serviceId\":" + serviceId + "}";
        return sendMessage(senderId, receiverId, content, ChatMessage.MessageType.SERVICE_INQUIRY, extraData);
    }
}
